﻿using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using monitor_2_DBwork;
using System.Net;
using System.Drawing;

namespace monitor_server_2
{
    public partial class DeviceList : Form
    {
        private string _lastState1;
        private string _lastState2;
        private TreeNode _selectedNode;
        private ContextMenuStrip _menu;
        MyForm _addDeviceForm = new MyForm();
        MyForm _addRegionForm = new MyForm();
        public delegate void RefreshTree();
        bool _success, _loginSuccess;

        public DeviceList()
        {
            InitializeComponent();
        }

        private void выходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void DeviceList_Load(object sender, EventArgs e)
        {
            _loginSuccess = new LoginForm(LoginForm.AccessType.Admin).ShowDialog() == DialogResult.Yes;
            if (!_loginSuccess)
                return;
            ImageInit();

            resetSNMPipMenuItem.Text = Main.Rm.GetString("ResetSNMPListenerIP");

            edit_accebtButton.Image = (Image)Main.Rm.GetObject("edit_image_16");
            cancelButton.Image = (Image) Main.Rm.GetObject("cancel_image_16");
            deleteButton.Image = (Image) Main.Rm.GetObject("delete_image_16");
            
            coordinatesSetter1.SetDestinations("N");
            coordinatesSetter1.DestText = "N";
            coordinatesSetter1.MinDegrees = 23;
            coordinatesSetter1.MaxDegrees = 32;

            coordinatesSetter2.SetDestinations("E");
            coordinatesSetter2.DestText = "E";
            coordinatesSetter2.MinDegrees = 51;
            coordinatesSetter2.MaxDegrees = 56;

            _menu = new ContextMenuStrip();
            _menu.ItemClicked += _menu_ItemClicked;
            Text = Main.Rm.GetString("DeviceList");
            TreeUpdate();
            tagBox1.ReadOnly = true;
            edit_accebtButton.Text = Main.Rm.GetString("Edit");
            cancelButton.Text = Main.Rm.GetString("Cancel");
            deleteButton.Text = Main.Rm.GetString("Delete");

            менюToolStripMenuItem.Text = Main.Rm.GetString("Menu");

            выходToolStripMenuItem.Text = Main.Rm.GetString("Close");
            выходToolStripMenuItem.Image = (Image) Main.Rm.GetObject("exit_16");

            var ilist = new ImageList();
            ilist.Images.Add((Image)Main.Rm.GetObject("emptyImage"));
            ilist.Images.Add((Image)Main.Rm.GetObject("Circle_Grey_16"));
            ilist.Images.Add((Image)Main.Rm.GetObject("Circle_Blue_16"));
            ilist.Images.Add((Image) Main.Rm.GetObject("antenna_16"));
            ilist.Images.Add((Image) Main.Rm.GetObject("direction_16"));
            deviceTree.ImageList = ilist;

            cancelButton.Visible = false;
            deleteButton.Visible = false;
            stationNameBox.Visible = false;
            stationNameLabel.Visible = false;
        }

        void ImageInit()
        {
            try
            {
                
                noCoordsPicture.Image = (Image)Main.Rm.GetObject("system_help");
            }
            catch (Exception)
            {
                noCoordsPicture.Image = null;
            }
            var tip = new ToolTip { ShowAlways = true };
            tip.SetToolTip(noCoordsPicture, Main.Rm.GetString("NoCoordinates"));
        }

        private void TreeUpdate()
        {
            deviceTree.Nodes.Clear();
            TreeNode[] nodes;
            try
            {
                nodes = DBwork.GetTree();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Main.Rm.GetString("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                _success = false;
                return;
            }
            if (nodes[0].Name.Contains("err:"))
            {
                MessageBox.Show(nodes[0].Name.Substring(4), Main.Rm.GetString("Error"), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                _success = false;
                return;
            }

            foreach (var regionNode in nodes)
            {
                //region
                regionNode.Tag = new DeviceTreeNodeOptions
                {
                    Type = DeviceTreeNodeType.Region,
                    MainStation = (string)regionNode.Tag
                };
                regionNode.SelectedImageIndex =
                    regionNode.ImageIndex = 4;

                foreach (TreeNode stationNode in regionNode.Nodes)
                {
                    //station
                    var split = ((string)stationNode.Tag).Split(';');
                    stationNode.Tag = new DeviceTreeNodeOptions
                    {
                        Type = DeviceTreeNodeType.Station,
                        Blr = split[0]
                    };
                    if (split[1].Length == 12)
                    {
                        ((DeviceTreeNodeOptions)stationNode.Tag).Coordinates1 = split[1].Substring(0, 6);
                        ((DeviceTreeNodeOptions)stationNode.Tag).Coordinates2 = split[1].Substring(6, 6);
                    }
                    stationNode.SelectedImageIndex =
                        stationNode.ImageIndex = 3;

                    foreach (TreeNode deviceNode in stationNode.Nodes)
                    {
                        //device
                        var pars = ((string)deviceNode.Tag).Split(';');
                        var active = bool.Parse(pars[1]);
                        deviceNode.Tag = new DeviceTreeNodeOptions
                        {
                            Type = DeviceTreeNodeType.Device,
                            IpAddress = pars[0],
                            Active = active
                            //IpAddress = (string)deviceNode.Tag
                        };
                        deviceNode.SelectedImageIndex = 
                        deviceNode.ImageIndex = active ? 2 : 1;
                    }
                }
            }
            
            deviceTree.Nodes.AddRange(nodes);
            deviceTree.ExpandAll();
            _success = true;
        }

        private void deviceTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var tree = (TreeView)sender;
            var node = tree.SelectedNode;
            groupBox.Text = node.Text;
            //var tag = node.Tag.ToString();
            var tag = (DeviceTreeNodeOptions)node.Tag;

            //if (node.Text.Contains("область"))
            if (tag.Type == DeviceTreeNodeType.Region)
            {
                tagName1.Text = Main.Rm.GetString("HeadStation");
                //tagBox1.Text = tag;
                tagBox1.Text = tag.MainStation;
                StationCoordsOptions("", false, true);
            }
            //else if (node.Text.Contains("РТПС"))
            else if (tag.Type == DeviceTreeNodeType.Station)
            {
                //var split = tag.Split(';');

                tagName1.Text = Main.Rm.GetString("BLR");
                //tagBox1.Text = split[0];
                tagBox1.Text = tag.Blr;

                stationNameLabel.Text = Main.Rm.GetString("Station");
                stationNameBox.Text = node.Text;

                coordsTag.Text = Main.Rm.GetString("Coordinates");
                //StationCoordsOptions(split[1], false, false);
                StationCoordsOptions(tag.Coordinates1 + tag.Coordinates2, false, false);

            }
            else if (tag.Type == DeviceTreeNodeType.Device)
            {
                tagName1.Text = Main.Rm.GetString("IPAddress");
                activateBoxLabel.Visible = true;
                activateCheckBox.Visible = true;
                activateCheckBox.CheckState = tag.Active ? CheckState.Checked : CheckState.Unchecked;

                ChangeActiveState(tag.Active);
                //tagBox1.Text = tag;
                tagBox1.Text = tag.IpAddress;

                StationCoordsOptions("", false, true);
            }
            if (tag.Type != DeviceTreeNodeType.Device)
            {
                activateCheckBox.Visible = false;
                activateBoxLabel.Visible = false;
            }
        }

        private void edit_accebtButton_Click(object sender, EventArgs e)
        {
            var but = (Button) sender;
                                                                                //Edit
            if (but.Text == Main.Rm.GetString("Edit"))
            {
                edit_accebtButton.Image = (Image)Main.Rm.GetObject("accept_image_16");
                _selectedNode = deviceTree.SelectedNode;
                if (_selectedNode == null)
                {
                    MessageBox.Show(Main.Rm.GetString("SelectInstance"));
                    return;
                }
                deviceTree.Enabled = false;
                but.Text = Main.Rm.GetString("Accept");
                cancelButton.Visible = true;
                if ((_selectedNode.Parent != null) && 
                    (((DeviceTreeNodeOptions)_selectedNode.Parent.Tag).Type == DeviceTreeNodeType.Station ||
                    ((DeviceTreeNodeOptions)_selectedNode.Tag).Type == DeviceTreeNodeType.Station))
                    deleteButton.Visible = true;
                else
                {
                    deleteButton.Visible = false;
                }
                if (((DeviceTreeNodeOptions) _selectedNode.Tag).Type == DeviceTreeNodeType.Station)
                {
                    stationNameBox.Visible = true;
                    stationNameLabel.Visible = true;
                }
                if (((DeviceTreeNodeOptions) _selectedNode.Tag).Type == DeviceTreeNodeType.Device)
                {
                    activateCheckBox.Enabled = true;
                }
                _lastState1 = tagBox1.Text;
                tagBox1.ReadOnly = false;
                //
                if (coordsTag.Visible)
                {
                    if(coordinatesSetter1.Visible)
                        _lastState2 = coordinatesSetter1.Coordinates + coordinatesSetter2.Coordinates;
                    else
                        _lastState2 = "";
                    StationCoordsOptions("", true, false);
                    //_lastState2 = tagBox2.Text;
                    //tagBox2.ReadOnly = false;
                }

            }
                                                                                //Accept
            else
            {
                
                bool upd;
                //if (_selectedNode.Text.Contains("область"))
                var tag = (DeviceTreeNodeOptions) _selectedNode.Tag;
                if(tag.Type == DeviceTreeNodeType.Region)
                {
                    upd = DBwork.UpdateData("region", _selectedNode.Text, tagBox1.Text);
                }
                else 
                    if(tag.Type == DeviceTreeNodeType.Station)
                {
                    var coords = new StringBuilder(12);
                    coords.Append(coordinatesSetter1.Coordinates);
                    coords.Append(coordinatesSetter2.Coordinates);

                    upd = DBwork.UpdateData("station", _selectedNode.Text, stationNameBox.Text, tagBox1.Text, coords.ToString());
                }
                else
                {
                    IPAddress ip;
                    if (!IPAddress.TryParse(tagBox1.Text, out ip))
                    {
                        MessageBox.Show(Main.Rm.GetString("WrongParameter") + @": " + Main.Rm.GetString("IPAddress"));
                        return;
                    }
                    bool active = activateCheckBox.CheckState == CheckState.Checked;
                    upd = DBwork.UpdateData("device", _selectedNode.Text, _selectedNode.Parent.Text, ip.ToString(), active.ToString());
                }
                if (!upd)
                {
                    MessageBox.Show(Main.Rm.GetString("Error"));
                    return;
                }
                MessageBox.Show(Main.Rm.GetString("Complete"));
                deviceTree.SelectedNode = _selectedNode;
                TreeUpdate();
                AfterEdit();
            }
            
        }

        private void AfterEdit()
        {
            edit_accebtButton.Image = (Image)Main.Rm.GetObject("edit_image_16");
            deviceTree.Enabled = true;
            edit_accebtButton.Text = Main.Rm.GetString("Edit");
            cancelButton.Visible = false;
            deleteButton.Visible = false;
            stationNameBox.Visible = false;
            stationNameLabel.Visible = false;
            activateCheckBox.Enabled = false;
            tagBox1.ReadOnly = true;
            if (coordsTag.Visible)
            {
                //tagBox2.ReadOnly = true;
                StationCoordsOptions(_lastState2, false, false);
            }
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            tagBox1.Text = _lastState1;
            //if (coordsTag.Visible)
            //{
            //    //tagBox2.Text = _lastState2;
            //    StationCoordsOptions(_lastState2, false, false);
            //}
            AfterEdit();

        }

        private void deleteButton_Click(object sender, EventArgs e)
        {

            DialogResult res = MessageBox.Show(
                Main.Rm.GetString("ConfirmDeleting") + '.',
                Main.Rm.GetString("ConfirmDeleting"),
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button1
                );
            if (res == DialogResult.No)
                return;
            var options = (DeviceTreeNodeOptions) _selectedNode.Tag;
            if (_selectedNode.Parent == null || 
                (((DeviceTreeNodeOptions)_selectedNode.Parent.Tag).Type != DeviceTreeNodeType.Station &&
                options.Type != DeviceTreeNodeType.Station))
                return;
            switch (options.Type)
            {
                case DeviceTreeNodeType.Device:
                    if (DBwork.DeleteData("device", _selectedNode.Text, _selectedNode.Parent.Text))
                    {
                        MessageBox.Show(Main.Rm.GetString("Complete"));
                        TreeUpdate();
                        AfterEdit();
                    }
                    else
                        MessageBox.Show(Main.Rm.GetString("Error"));
                    break;
                case DeviceTreeNodeType.Station:
                    if (DBwork.DeleteData("station", _selectedNode.Text))
                    {
                        MessageBox.Show(Main.Rm.GetString("Complete"));
                        TreeUpdate();
                        AfterEdit();
                    }
                    else
                        MessageBox.Show(Main.Rm.GetString("Error"));
                    break;
                default:
                    return;
            }
            
        }

        private void deviceTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button != MouseButtons.Right)
                return;
            ((TreeView)sender).SelectedNode = e.Node;
            if (((DeviceTreeNodeOptions)e.Node.Tag).Type != DeviceTreeNodeType.Station &&
                ((DeviceTreeNodeOptions)e.Node.Tag).Type != DeviceTreeNodeType.Region)
                return;
            _menu.Items.Clear();
            switch (((DeviceTreeNodeOptions)e.Node.Tag).Type)
            {
                case DeviceTreeNodeType.Station:
                    _menu.Items.Add(Main.Rm.GetString("AddDevice"));
                    break;
                case DeviceTreeNodeType.Region:
                    _menu.Items.Add(Main.Rm.GetString("AddRegion"));
                    break;
            }
            _menu.Show(MousePosition);
        }

        void _menu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Text == Main.Rm.GetString("AddDevice"))
            {
                if (_addDeviceForm.IsNull)
                {
                    RefreshTree del = TreeUpdate;
                    Form newAddDeviceForm = new AddDevice(deviceTree.SelectedNode, del);
                    newAddDeviceForm.Owner = this;
                    _addDeviceForm = new MyForm(newAddDeviceForm);
                }
                else
                {
                    _addDeviceForm.Show();
                }
            }

            if (e.ClickedItem.Text == Main.Rm.GetString("AddRegion"))
            {
                if (_addRegionForm.IsNull)
                {
                    RefreshTree del = TreeUpdate;
                    Form newAddRegionForm = new AddRegion(deviceTree.SelectedNode, del);
                    newAddRegionForm.Owner = this;
                    _addRegionForm = new MyForm(newAddRegionForm);
                }
                else
                {
                    _addRegionForm.Show();
                }
            }
        }

        /// <summary>
        /// Настройка контрола с координатами.
        /// </summary>
        /// <param name="coords">Координаты для отображения.</param>
        /// <param name="edit">Необходимость редактирования координат.</param>
        /// <param name="hide">Необходимость спрятать контрол.</param>
        void StationCoordsOptions(string coords, bool edit, bool hide)
        {
            if (hide)
            {
                coordinatesSetter1.Visible = false;
                coordinatesSetter2.Visible = false;
                coordsTag.Visible = false;
                noCoordsPicture.Visible = false;
                return;
            }
            coordinatesSetter1.Visible = true;
            coordinatesSetter2.Visible = true;
            coordsTag.Visible = true;
            if (edit)
            {
                coordinatesSetter1.ReadOnly = false;
                coordinatesSetter2.ReadOnly = false;
                noCoordsPicture.Visible = false;
            }
            else
            {
                coordinatesSetter1.ReadOnly = true;
                coordinatesSetter2.ReadOnly = true;

                if (coords == null || coords.Length != 12)
                {
                    coordinatesSetter1.Visible = false;
                    coordinatesSetter2.Visible = false;
                    noCoordsPicture.Visible = true;
                    return;
                }
                noCoordsPicture.Visible = false;
                coordinatesSetter1.Coordinates = coords.Substring(0, 6);
                coordinatesSetter2.Coordinates = coords.Substring(6, 6);
            }

        }

        private void DeviceList_Shown(object sender, EventArgs e)
        {
            if (!_success || !_loginSuccess)
                Close();
        }

        private void ChangeActiveState(bool active)
        {
            var sb = new StringBuilder();
            sb.Append(Main.Rm.GetString("Status") + ": ");
            sb.Append(active
                          ? Main.Rm.GetString("activateActiveBoxLabelText")
                          : Main.Rm.GetString("activateInactiveBoxLabelText"));
            activateBoxLabel.Text = sb.ToString();
            var l = activateBoxLabel.Location;
            l.X = 193 - activateBoxLabel.Size.Width;
            activateBoxLabel.Location = l;
        }

        private void activateCheckBox_CheckStateChanged(object sender, EventArgs e)
        {
            var cb = (CheckBox) sender;
            bool active = cb.CheckState == CheckState.Checked;
            ChangeActiveState(active);
        }

        private void resetSNMPipMenuItem_Click(object sender, EventArgs e)
        {
            var chk = DBwork.AddOrSetOptionValue(ServerLib.Server.CurrentIpToListenValueName, "0.0.0.0");
            if (chk.Equals("ok"))
            {
                MessageBox.Show(@"Чтобы выбрать новый IP-адрес, необходимо перезапустить сервер.");
            }
        }
    }
}
